/*
Copyright 2008  Four Roads LLC conact@4-roads.com

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either 
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Web.UI;
using System.Text;
using System.Collections;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using CommunityServer.Components;
using CommunityServer.Controls;
using ResourceManager = FourRoads.Links.Controls.ResourceManager;
using CA = ComponentArt.Web.UI;

namespace FourRoads.Links.Controls
{
	using DataProvider;

	/// <summary>
	/// Summary description for ResLinkLinkView.
	/// </summary>
	public class ResLinkLinkView : ResLinkSkinExTemplatedWebControl
	{
		#region Child Controls
		HyperLink _Title = null;
		HtmlAnchor _BrokenLink = null;
		Literal _Description = null;
		Literal _HitCounter = null;
		ResLinkRateLink _Rating = null;
		ModalLink _AddComment = null;
		Repeater _CommentRpt = null;
		System.Web.UI.HtmlControls.HtmlGenericControl _MainLinkHolder = null;
		LinkModeration _Moderation = null;
		LinkButton _DisplayComments  = null;
		CA.CallBack _LinkCommentsCallback = null;
		#endregion

		public ResLinkLinkView()
		{

		}

		protected override Post PostData
		{
			get
			{
				return LinkPost;
			}
		}

		ResLinkLink _Post = null;
		public ResLinkLink LinkPost
		{
			get
			{
				if (_Post == null)
				{
					//try and get it feom the section
					_Post = ThisSection.FindLink(PostID);
				}

				return _Post;
			}
			set
			{
				_Post = value;
				PostID = _Post.PostID;
			}
		}

		private bool _BookMark = false;
		public bool BookMark
		{
			set
			{
				_BookMark = value;
			}
		}

		private string idPostID
		{
			get{return "postID:" + UniqueID;}
		}

		public bool ModerationView
		{
			get
			{
				if (ViewState["ModerationView"] == null)
					ViewState["ModerationView"] = false;

				return (bool)ViewState["ModerationView"];
			}

			set
			{
				ViewState["ModerationView"] = value;
			}
		}

		private int PostID
		{
			get
			{
				if (ViewState[idPostID] == null)
					ViewState[idPostID] = CSContext.Current.GetIntFromQueryString("LinkID" , -1);

				return (int)ViewState[idPostID];
			}

			set
			{
				ViewState[idPostID] = value;
			}
		}

		protected override void AttachChildControls()
		{
			base.AttachChildControls();

			_Title = FindControl("Title") as HyperLink;
			_BrokenLink = FindControl("ReportBroken") as HtmlAnchor;
			_Description =  FindControl("Description") as Literal;
			_HitCounter=  FindControl("HitCounter") as Literal;
			_Rating =  FindControl("LinkRating") as ResLinkRateLink;
			_DisplayComments = FindControl("DisplayComments") as LinkButton;
			_LinkCommentsCallback =  FindControl("LinkCommentsCallback") as CA.CallBack;

			_AddComment =  FindControl("AddCommentBtn") as ModalLink;
			_CommentRpt =  FindControl("CommentRepeater") as Repeater;
			_MainLinkHolder =  FindControl("mainLinkHolder") as System.Web.UI.HtmlControls.HtmlGenericControl;
			_Moderation = FindControl("LinkModeration") as LinkModeration;
			_CommentRpt.ItemCreated += new RepeaterItemEventHandler(_CommentRpt_ItemDataBound);
		
			_DisplayComments.Attributes.Add("onclick" , string.Format("javascript:return ToggleComments('{0}' , {1});" , FindControl("LinkCommentDisplay").ClientID , _LinkCommentsCallback.ClientID ));
			_DisplayComments.CausesValidation =false;

			Page.RegisterClientScriptBlock("clientCommentCallbackScript", clientCommentCallbackScript);

			_LinkCommentsCallback.Callback += new ComponentArt.Web.UI.CallBack.CallbackEventHandler(_LinkCommentsCallback_Callback);
		}


		public void CreateCommentAddedScript()
		{
			StringBuilder str = new StringBuilder();

			str.Append("<script language='javascript' type='text/javascript' >function linkCommentAdded(id){var items = id.split(\":\"); var linkID=items[0]; var commentID=items[1];");
			str.Append("if (linkID != '0')DisplayComments('" + FindControl("LinkCommentDisplay").ClientID + "' , "+ _LinkCommentsCallback.ClientID + " , linkID);}");
			str.Append("</script>");

			Page.RegisterClientScriptBlock("AddCommentCallBackFunc", str.ToString());
		}

		private string clientCommentCallbackScript = @"
			<script language=""javascript""  Type=""text/javascript"" >
				function DisplayComments(displayID , callbackID , param)
				{
					var lnkComment = document.getElementById(displayID);

					lnkComment.style.display = 'block';
					callbackID.Callback(param);
				}

				function ToggleComments(displayID , callbackID)
				{
					var lnkComment = document.getElementById(displayID);
							
					if (lnkComment.style.display == 'none')
					{
						DisplayComments(displayID , callbackID , '');
					}
					else
					{
						lnkComment.style.display = 'none';
					}
							
					return false;
				}
			</script>";		

		public override void DataBind()
		{
			base.DataBind();

			if (LinkPost != null)
			{
				_Moderation.Post = LinkPost;
				_Moderation.Section = ThisSection;

				_MainLinkHolder.Visible = true;

				//This link has been bookmarked so we need to create a 
				HtmlAnchor anchor = new HtmlAnchor();
				anchor.Name = LinkPost.PostID.ToString();
				_MainLinkHolder.Controls.Add(anchor);

				//Broken Link
				if (!ReportDeadLinksRight || !ViewLinksRight || ThisSection.Links.Length == 0)
				{
					_BrokenLink.Visible = false;
				}
				else
				{
					if (LinkPost.ReportedDead)
					{
						_BrokenLink.Title = ResourceManager.GetString ("ResLinkLinkView_BrokenLinkReported");
						_BrokenLink.InnerText = _BrokenLink.Title;
						_BrokenLink.Attributes.Add("onclick" ,"return false;");
					}
					else
					{
						_BrokenLink.Attributes.Add("onclick" , string.Format("ajaxReportBrokenLink('{0}' , {1});return false;" , this.ClientID , LinkPost.PostID ) );
					}
				}

				//Hit Counter
				_HitCounter.Visible =  ThisSection.DisplayHitCounter;
				_HitCounter.Text = string.Format(ResourceManager.GetString("ResLinkLinkView_HitCounterText") , LinkPost.Views);
				
				//Title
				_Title.Text = LinkPost.Subject;
				_Title.NavigateUrl = LinkPost.LinkUrl;
				_Title.ToolTip = string.Format(ResourceManager.GetString("ShowResourceLink_ToolTip") , _Title.Text);
				_Title.Attributes.Add("onclick" , string.Format("ajaxClickLink('{0}' , {1});return true;" , this.ClientID , LinkPost.PostID ) );
				//Body
				if (_Description != null)
					_Description.Text = LinkPost.Body;

				//Rating
				if (_Rating != null)
				{
					_Rating.Post = LinkPost;
					_Rating.PostID = LinkPost.PostID;
					_Rating.SectionID = LinkPost.SectionID;

					if(LinkPost.RatingSum < 0 || ThisSection.EnableRatings == false)
						_Rating.Visible = false;
				}	

				_AddComment.Url = ResLinkUrls.Instance().AddComment(LinkPost.SectionID , LinkPost.PostID);

				DataBindComments();
			}
			else
			{
				_MainLinkHolder.Visible = false;
			}


			UpdateModerationView();
		}

		private void UpdateModerationView()
		{
			if (ModerationView)
			{
				//Hide all of the buttons
				_AddComment.Visible = false;
				_Moderation.Visible = true;
				_BrokenLink.Visible = false;
			}
		}

		private void DataBindComments()
		{	
			//If the enable comments feature is not set then we still want ot be able to view the existing 
			//comments
			if (!AddCommentsRight || LinkPost.Subject == "" || ThisSection.EnableComments == false)
			{
				_AddComment.Visible = false;
			}
			else
			{
				_AddComment.Visible = true;
			}

			//TODO: Figure out comment count without getting the comments
			if (LinkPost.CommentCount == 0)
			{
				_DisplayComments.Visible = false;
			}
		}

		/// <summary>
		/// This method is used for link tracking
		/// </summary>
		/// <returns></returns>
		private void CreateClickThroughJavaScript()
		{
			StringBuilder sb = new StringBuilder();

			sb.Append("\n<script language='javascript' type=\"text/javascript\">\n");
			sb.Append("\nfunction ajaxClickLink(containerID , postID)\n{\n\nResLinkLinkView.ClickLink(containerID, postID , null);\n}\n");
			sb.Append("\n</script>");

			Page.RegisterClientScriptBlock("ClickLinkAJAXCallbacks", sb.ToString());
		}

		[AjaxMethod(IncludeControlValuesWithCallBack = false)]
		public void ClickLink(int postID)
		{
			ResLinkDataProvider dp = ResLinkDataProvider.Instance();

			dp.UpdateLinkHitCount(ThisSection.SectionID ,  postID);
		}

		public void CreateBrokenLinkJavascript()
		{
			StringBuilder sb = new StringBuilder();

			sb.Append("\n<script language='javascript' type=\"text/javascript\">\n");
			sb.Append("\nfunction ajaxReportBrokenLink(containerID , postID)\n{\n\nResLinkLinkView.BrokenLink_Click(containerID, postID , ajaxReportBrokenLinkResponse);\n}\n");
			sb.AppendFormat("\nfunction ajaxReportBrokenLinkResponse(result)\n{{if(result.value == true) alert('{0}');}}\n" , ResourceManager.GetString("ResLinksSection_DeadLinkReport") );
			sb.Append("\n</script>");

			Page.RegisterClientScriptBlock("ReportBrokenLinkAJAXCallbacks", sb.ToString());
		}

		[AjaxMethod(IncludeControlValuesWithCallBack = false)]
		public bool BrokenLink_Click(int postID)
		{
			//This link is broken so add it to the broken links list and 
			ResLinkDataProvider dp = ResLinkDataProvider.Instance();

			ResLinkLink lnk = ThisSection.FindLink(PostID);

			if (lnk != null)
			{
				CSEvents.PrePost(lnk,ObjectState.Update,(ApplicationType)ExApplicationType.ResLink);
				CSEvents.BeforePost(lnk,ObjectState.Update,(ApplicationType)ExApplicationType.ResLink);

				dp.ReportDeadLink(postID , CSContext.Current.User.UserID );

				CSEvents.AfterPost(lnk,ObjectState.Update,(ApplicationType)ExApplicationType.ResLink);

				return true;
			}

			return false;
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad (e);

			if (!Page.IsPostBack)
			{
				DataBind();
			}
			
		}

		private void _CommentRpt_ItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			//Populate the comments in here
			if (e.Item.ItemType == ListItemType.Item || 
				e.Item.ItemType == ListItemType.AlternatingItem )
			{
				ResLinkCommentRateLink ratingImageButton = e.Item.FindControl("CommentRating") as ResLinkCommentRateLink;
				Literal textComment = e.Item.FindControl("LinkComment") as Literal;
				HyperLink userDet = e.Item.FindControl("LinkCommentUser") as HyperLink;
				CommentModeration mod = e.Item.FindControl("CommentModeration") as CommentModeration;
				
				ResLinkComments com =  (ResLinkComments)e.Item.DataItem;

				e.Item.Visible = !ModerationView || (ModerationView && !com.IsApproved);

				mod.CallbackClientID = "function(result){" + _LinkCommentsCallback.ClientID + ".Callback();}";;
				mod.Post = LinkPost;
				mod.Section = ThisSection;
				mod.Comment = com;

				HtmlAnchor anchor = new HtmlAnchor();
				anchor.Name = com.ParentID.ToString() + "-" + com.PostID.ToString();
				e.Item.Controls.Add(anchor);

				ratingImageButton.Visible = com.CommentRating >= 0;
				ratingImageButton.AjaxCall = AjaxCall;
				ratingImageButton.Comment = com;
				ratingImageButton.EnableUserRating = false;

				textComment.Text = com.FormattedBody;
				userDet.Text = string.Format("{0} {1} {2}" , com.User.DisplayName , ResourceManager.GetString("ResLinkCommentSeperator")  , Formatter.FormatDate(com.PostDate, true));
				userDet.NavigateUrl = SiteUrls.Instance().UserProfile(com.User.UserID);
			}
		}

		protected override void OnInit(EventArgs e)
		{
			AjaxManager.Register(this , "ResLinkLinkView" , true , AjaxDebug.None );

			CreateCommentAddedScript();
			CreateBrokenLinkJavascript();
			CreateClickThroughJavaScript();

			base.OnInit (e);
		}
	
		private bool AjaxCall = false;

		private void _LinkCommentsCallback_Callback(object sender, ComponentArt.Web.UI.CallBackEventArgs e)
		{
			try
			{	
				if (e.Parameter == "-1")
					FindControl("CommentReceived").Visible = true;

				AjaxCall = true;
				_CommentRpt.Visible = true;
				_CommentRpt.DataSource = LinkPost.Comments;
				_CommentRpt.DataBind();

			}
			catch(Exception ex)
			{
				System.Diagnostics.Trace.Write(ex.ToString());
				throw;
			}

			_CommentRpt.RenderControl(e.Output);
		}
	}
}
